<?php //-->
/*
 * This file is part a custom application package.
 * (c) 2011-2012 Openovate Labs
 */

/**
 * Pagination block
 */
class Front_Block_Methods extends Eden_Block {
	/* Constants
	-------------------------------*/
	/* Public Properties
	-------------------------------*/
	/* Protected Properties
	-------------------------------*/
	protected $_path 	= NULL;
	protected $_chain 	= NULL;
	protected $_exclude = array();
	
	/* Private Properties
	-------------------------------*/
	/* Magic
	-------------------------------*/
	/* Public Methods
	-------------------------------*/
	/**
	 * This Block has pagination we need to pass in the url
	 *
	 * @param array
	 * @return this
	 */
	public function setPath($path) {
		$this->_path = $path;
		return $this;
	}
	
	/**
	 * This Block has pagination we need to pass in the url
	 *
	 * @param array
	 * @return this
	 */
	public function setChain($chain) {
		$this->_chain = $chain;
		return $this;
	}
	
	/**
	 * This Block has pagination we need to pass in the url
	 *
	 * @param array
	 * @return this
	 */
	public function exclude(array $methods) {
		$this->_exclude = $methods;
		return $this;
	}
	
	/**
	 * Returns the template variables in key value format
	 *
	 * @param array data
	 * @return array
	 */
	public function getVariables() {
		$library	= front()->registry()->get('path', 'library').'/eden';
		
		$code = eden('file', $library.'/'.$this->_path)->getContent();
		$notes = $this->_getNotes($code);
		return array(
			'notes' 	=> $notes, 
			'chain' 	=> $this->_chain, 
			'exclude' 	=> $this->_exclude);
	}
	
	/**
	 * Returns a template file
	 * 
	 * @param array data
	 * @return string
	 */
	public function getTemplate() {
		return realpath(dirname(__FILE__).'/methods.phtml');
	}
	
	/* Protected Methods
	-------------------------------*/
	protected function _getNotes($code) {
		$lines = explode("\n", $code);
		$notes = array();
		$section = 'unknown';
		$class = 'unknown';
		foreach($lines as $i => $line) {
			if(preg_match("#-+\*/#", $line)) {
				$section = trim(str_replace('/*', '', $lines[$i-1]));
				$notes[$class][$section] = array();
				continue;
			}
			
			if(strpos(trim($line), '/**') === 0) {
				$doc = $this->_getJavaDoc($lines, $i);
				if($doc['meta']['type'] == 'class') {
					$class = $doc['meta']['name'];
					$notes[$class] = $doc;
					continue;
				}
				
				$notes[$class][$section][] = $doc;
				continue;
			} 
			
			if(strpos(trim($line), 'const') === 0) {
				list($key, $value) = explode('=', str_replace(array('const', ';', '\'', '"'), '', $line));
				if($value === true) {
					$value = 'true';
				} else if($value === false) {
					$value = 'false';
				} else if(is_null($value)) {
					$value = 'null';
				}
				$notes[$class]['Constants'][trim($key)] = trim($value);
				continue;
			}
			
			if(strpos(trim($line), 'public $') === 0) {
				list($key, $value) = explode('=', str_replace('public', '', $line));
				$notes[$class]['Public Properties'][] = trim($key);
				continue;
			}
			
			if(strpos(trim($line), 'protected $') === 0) {
				list($key, $value) = explode('=', str_replace('protected', '', $line));
				$notes[$class]['Public Properties'][] = trim($key);
				continue;
			}
			
			if(strpos(trim($line), 'private $') === 0) {
				list($key, $value) = explode('=', str_replace('private', '', $line));
				$notes[$class]['Public Properties'][] = trim($key);
				continue;
			}
		}
		
		return $notes;
	}
	
	protected function _getJavaDoc($lines, &$i) {
		$description = $code = NULL;
		$attributes = $meta = array();
		$meta['type'] = 'unknown';
		$mode = true;
		for($i++; $i < count($lines); $i++) {
			$line = trim(preg_replace("/^\s+\*\s*/", '', $lines[$i]));
			
			if($line == '/') {
				$i++;
				break;
			} 
			
			if(strpos($line, '@') === 0) {
				$mode = false;
				list($key, $value) = explode(' ', substr($line, 1), 2);
				if(isset($attributes[$key])) {
					if(!is_array($attributes[$key])) {
						$attributes[$key] = array($attributes[$key]);
					}
					
					$attributes[$key][] = trim($value);
					continue;
				}
				
				$attributes[$key] = trim($value);
				continue;
			}
			
			if(!$mode) {
				if(is_array($attributes[$key])) {
					$attributes[$key][count($attributes[$key])-1] .= ' '.$line;
					continue;
				}
				
				$attributes[$key] .= ' '.$line;
				continue;
			}
			
			$description[] = $line;
		}
		
		if(isset($lines[$i]) && strpos($lines[$i], 'class') !== false) {
			$meta = array(
				'name'			=> NULL,
				'type' 			=> 'class',
				'abstract' 		=> false,
				'extends' 		=> NULL,
				'implements' 	=> array());
				
			preg_match("/class\s([a-zA-Z0-9-_]+)/", $lines[$i], $matches);
			if(isset($matches[1])) {
				$meta['name'] = $matches[1];
			}
			
			preg_match("/extends\s([a-zA-Z0-9-_]+)/", $lines[$i], $matches);
			if(isset($matches[1])) {
				$meta['extends'] = $matches[1];
			}
			
			preg_match("/implements\s([a-zA-Z0-9-_\,\s]+)/", $lines[$i], $matches);
			if(isset($matches[1])) {
				$meta['implements'] = explode(',', $matches[1]);
			}
		}
		
		if(isset($lines[$i]) && strpos($lines[$i], 'function') !== false) {
			$meta = array(
				'name'			=> NULL,
				'type' 			=> 'function',
				'abstract' 		=> false,
				'static' 		=> false,
				'access' 		=> NULL);
			
			preg_match("/function\s([a-zA-Z0-9-_]+)/", $lines[$i], $matches);
			$meta['name'] = $matches[1];
			
			if(strpos($lines[$i], 'static') !== false) {
				$meta['static'] = true;
			}
			
			if(strpos($lines[$i], 'public') !== false) {
				$meta['access'] = 'public';
			}
			
			if(strpos($lines[$i], 'protected') !== false) {
				$meta['access'] = 'protected';
			}
			
			if(strpos($lines[$i], 'private') !== false) {
				$meta['access'] = 'private';
			}
		}
		
		if(isset($lines[$i]) && strpos($lines[$i], 'abstract') !== false) {
			$meta['abstract'] = true;
		}
		
		if(isset($lines[$i])) {
			$code = trim(preg_replace("/\s*\{/", '', $lines[$i]));
		}
			
		return array(
			'code' 			=> $code,
			'meta' 			=> $meta,
			'description' 	=> $description, 
			'attributes' 	=> $attributes);
	}
	
	/* Private Methods
	-------------------------------*/
}